let x_PI = (`3.14159265358979324` * 3000.0) / 180.0;
let PI = `3.1415926535897932384626`;
let a = 6378245.0;
let ee = `0.00669342162296594323`;

//定义一些常量

/**
 * 百度坐标系 (BD-09) 与 火星坐标系 (GCJ-02)的转换
 * 即 百度 转 谷歌、高德
 * @param bd_lon
 * @param bd_lat
 * @returns {*[]}
 */
export const bd09togcj02 = function bd09togcj02(bd_lon, bd_lat) {
  bd_lon = +bd_lon;
  bd_lat = +bd_lat;
  var x = bd_lon - 0.0065;
  var y = bd_lat - 0.006;
  var z = Math.sqrt(x * x + y * y) - 0.00002 * Math.sin(y * x_PI);
  var theta = Math.atan2(y, x) - 0.000003 * Math.cos(x * x_PI);
  var gg_lng = z * Math.cos(theta);
  var gg_lat = z * Math.sin(theta);
  return [gg_lng, gg_lat];
};

/**
 * 火星坐标系 (GCJ-02) 与百度坐标系 (BD-09) 的转换
 * 即谷歌、高德 转 百度
 * @param lng
 * @param lat
 * @returns {*[]}
 */
export const gcj02tobd09 = function gcj02tobd09(lng, lat) {
  lat = +lat;
  lng = +lng;
  var z = Math.sqrt(lng * lng + lat * lat) + 0.00002 * Math.sin(lat * x_PI);
  var theta = Math.atan2(lat, lng) + 0.000003 * Math.cos(lng * x_PI);
  var bd_lng = z * Math.cos(theta) + 0.0065;
  var bd_lat = z * Math.sin(theta) + 0.006;
  return [bd_lng, bd_lat];
};
/**
 * WGS84转GCj02
 * @param lng
 * @param lat
 * @returns {*[]}
 */
export const wgs84togcj02 = function wgs84togcj02(lng, lat) {
  lat = +lat;
  lng = +lng;
  if (out_of_china(lng, lat)) {
    return [lng, lat];
  } else {
    var dlat = transformlat(lng - 105.0, lat - 35.0);
    var dlng = transformlng(lng - 105.0, lat - 35.0);
    var radlat = (lat / 180.0) * PI;
    var magic = Math.sin(radlat);
    magic = 1 - ee * magic * magic;
    var sqrtmagic = Math.sqrt(magic);
    dlat = (dlat * 180.0) / (((a * (1 - ee)) / (magic * sqrtmagic)) * PI);
    dlng = (dlng * 180.0) / ((a / sqrtmagic) * Math.cos(radlat) * PI);
    var mglat = lat + dlat;
    var mglng = lng + dlng;
    return [mglng, mglat];
  }
};
export const CGS2000ToWGS84 = function CGS2000ToWGS84(X, Y) {
  let pt = null;
  let L0 = 117; //中央子午线需根据实际情况设置
  let lat, lon;
  Y -= 500000;
  let result = [];
  let iPI = 0.0174532925199433; //pi/180
  let a = 6378137.0; //长半轴 m
  let b = 6356752.31414; //短半轴 m
  // let f = 1 / 298.257222101; //扁率 a-b/a
  let e = 0.0818191910428; //第一偏心率 Math.sqrt(5)
  let ee = Math.sqrt(a * a - b * b) / b; //第二偏心率
  let bf = 0; //底点纬度
  let a0 =
    1 +
    (3 * e * e) / 4 +
    (45 * e * e * e * e) / 64 +
    (175 * e * e * e * e * e * e) / 256 +
    (11025 * e * e * e * e * e * e * e * e) / 16384 +
    (43659 * e * e * e * e * e * e * e * e * e * e) / 65536;
  let b0 = X / (a * (1 - e * e) * a0);
  let c1 =
    (3 * e * e) / 8 +
    (3 * e * e * e * e) / 16 +
    (213 * e * e * e * e * e * e) / 2048 +
    (255 * e * e * e * e * e * e * e * e) / 4096;
  let c2 =
    (21 * e * e * e * e) / 256 +
    (21 * e * e * e * e * e * e) / 256 +
    (533 * e * e * e * e * e * e * e * e) / 8192;
  let c3 =
    (151 * e * e * e * e * e * e * e * e) / 6144 +
    (151 * e * e * e * e * e * e * e * e) / 4096;
  let c4 = (1097 * e * e * e * e * e * e * e * e) / 131072;
  bf =
    b0 +
    c1 * Math.sin(2 * b0) +
    c2 * Math.sin(4 * b0) +
    c3 * Math.sin(6 * b0) +
    c4 * Math.sin(8 * b0); // bf =b0+c1*sin2b0 + c2*sin4b0 + c3*sin6b0 +c4*sin8b0 +...
  let tf = Math.tan(bf);
  let n2 = ee * ee * Math.cos(bf) * Math.cos(bf); //第二偏心率平方成bf余弦平方
  let c = (a * a) / b;
  let v = Math.sqrt(1 + ee * ee * Math.cos(bf) * Math.cos(bf));
  let mf = c / (v * v * v); //子午圈半径
  let nf = c / v; //卯酉圈半径
  //纬度计算
  lat =
    bf -
    (tf / (2 * mf)) *
      Y *
      (Y / nf) *
      (1 -
        (1 / 12) *
          (5 + 3 * tf * tf + n2 - 9 * n2 * tf * tf) *
          ((Y * Y) / (nf * nf)) +
        (1 / 360) *
          (61 + 90 * tf * tf + 45 * tf * tf * tf * tf) *
          ((Y * Y * Y * Y) / (nf * nf * nf * nf)));
  //经度偏差
  lon =
    (1 / (nf * Math.cos(bf))) * Y -
    (1 / (6 * nf * nf * nf * Math.cos(bf))) *
      (1 + 2 * tf * tf + n2) *
      Y *
      Y *
      Y +
    (1 / (120 * nf * nf * nf * nf * nf * Math.cos(bf))) *
      (5 + 28 * tf * tf + 24 * tf * tf * tf * tf) *
      Y *
      Y *
      Y *
      Y *
      Y;
  result[0] = lat / iPI;
  result[1] = L0 + lon / iPI;
  //System.out.println(result[1]+","+result[0]);
  pt = [result[1], result[0]];
  return pt;
};
/**
 * GCJ02 转换为 WGS84
 * @param lng
 * @param lat
 * @returns {*[]}
 */
export const gcj02towgs84 = function gcj02towgs84(lng, lat) {
  lat = +lat;
  lng = +lng;
  if (out_of_china(lng, lat)) {
    return [lng, lat];
  } else {
    var dlat = transformlat(lng - 105.0, lat - 35.0);
    var dlng = transformlng(lng - 105.0, lat - 35.0);
    var radlat = (lat / 180.0) * PI;
    var magic = Math.sin(radlat);
    magic = 1 - ee * magic * magic;
    var sqrtmagic = Math.sqrt(magic);
    dlat = (dlat * 180.0) / (((a * (1 - ee)) / (magic * sqrtmagic)) * PI);
    dlng = (dlng * 180.0) / ((a / sqrtmagic) * Math.cos(radlat) * PI);
    var mglat = lat + dlat;
    var mglng = lng + dlng;
    return [lng * 2 - mglng, lat * 2 - mglat];
  }
};
var transformlat = function transformlat(lng, lat) {
  lat = +lat;
  lng = +lng;
  var ret =
    -100.0 +
    2.0 * lng +
    3.0 * lat +
    0.2 * lat * lat +
    0.1 * lng * lat +
    0.2 * Math.sqrt(Math.abs(lng));
  ret +=
    ((20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) *
      2.0) /
    3.0;
  ret +=
    ((20.0 * Math.sin(lat * PI) + 40.0 * Math.sin((lat / 3.0) * PI)) * 2.0) /
    3.0;
  ret +=
    ((160.0 * Math.sin((lat / 12.0) * PI) + 320 * Math.sin((lat * PI) / 30.0)) *
      2.0) /
    3.0;
  return ret;
};

var transformlng = function transformlng(lng, lat) {
  lat = +lat;
  lng = +lng;
  var ret =
    300.0 +
    lng +
    2.0 * lat +
    0.1 * lng * lng +
    0.1 * lng * lat +
    0.1 * Math.sqrt(Math.abs(lng));
  ret +=
    ((20.0 * Math.sin(6.0 * lng * PI) + 20.0 * Math.sin(2.0 * lng * PI)) *
      2.0) /
    3.0;
  ret +=
    ((20.0 * Math.sin(lng * PI) + 40.0 * Math.sin((lng / 3.0) * PI)) * 2.0) /
    3.0;
  ret +=
    ((150.0 * Math.sin((lng / 12.0) * PI) +
      300.0 * Math.sin((lng / 30.0) * PI)) *
      2.0) /
    3.0;
  return ret;
};

/**
 * 判断是否在国内，不在国内则不做偏移
 * @param lng
 * @param lat
 * @returns {boolean}
 */
var out_of_china = function out_of_china(lng, lat) {
  lat = +lat;
  lng = +lng;
  // 纬度3.86~53.55,经度73.66~135.05
  return !(lng > 73.66 && lng < 135.05 && lat > 3.86 && lat < 53.55);
};
